﻿#pragma once
#include "AsMathBasic.h"

class AS_MATH_API AsMathRect {
public:
	AsMathRect();
	AsMathRect(int x, int y, int width, int height);
	AsMathRect(const cv::Point& topLeft, const cv::Point& bottomRight);
	AsMathRect(const cv::Rect_<int>& rect);
	AsMathRect(const cv::Rect_<float>& rect);
	AsMathRect(const cv::Rect_<double>& rect);

private:
	double mTop;
	double mLeft;
	double mRight;
	double mBottom;

public:
	std::string tostr() const;

public:
	int x() const;
	int y() const;
	int width() const;
	int height() const;
	double widthF() const;
	double heightF() const;
	double top() const;
	double bottom() const;
	double left() const;
	double right() const;
	cv::Point topLeft() const;
	cv::Point topRight() const;
	cv::Point bottomLeft() const;
	cv::Point bottomRight() const;
	cv::Point center() const;
	cv::Rect rect() const;
	double scaleX(double x) const;
	double scaleY(double y) const;

public:
	void setX(double x);
	void setY(double y);
	void setXY(double x, double y);
	void setWidth(int width);
	void setHeight(int height);
	void setWidthF(double width);
	void setHeightF(double height);
	void setSize(int width, int height);
	void setSizeF(double width, double height);

	void setTop(double y);
	void setBottom(double y);
	void setLeft(double x);
	void setRight(double x);
	void setTopLeft(double x, double y);
	void setTopRight(double x, double y);
	void setBottomLeft(double x, double y);
	void setBottomRight(double x, double y);

	void moveX(double movx);
	void moveY(double movy);
	void moveXY(double movx, double movy);
	void moveTop(double movy);
	void moveBottom(double movy);
	void moveLeft(double movx);
	void moveRight(double movx);
	void moveTopLeft(double movx, double movy);
	void moveTopRight(double movx, double movy);
	void moveBottomLeft(double movx, double movy);
	void moveBottomRight(double movx, double movy);

	void expand(double val);
	void expand(double valx, double valy);
	void shrink(double val);
	void shrink(double valx, double valy);
	
	void zoom(double scale);
	void zoom(double scale, double anchor_x, double anchor_y);
	void zoom_center(double scale);

public:
	bool isIntersect(const cv::Rect& rect) const;
	bool isIntersect(const AsMathRect& rect) const;
	bool containsX(double x) const;
	bool containsY(double y) const;
	bool contains(const cv::Point& p) const;
	bool contains(const cv::Rect& rect) const;
	bool contains(const std::vector<cv::Point>& points, std::vector<cv::Point>& containsPoints) const;
	int countContains(const std::vector<cv::Point>& points) const;

public:
	std::vector<cv::Rect> split2X(double x) const;
	std::vector<cv::Rect> split2Y(double y) const;
	std::vector<cv::Rect> split4(double x, double y) const;

	AsMathRect getIntersectingRect(const AsMathRect& rect) const;

public:
	void getBorderPoints(std::vector<cv::Point>& outputPoints, double interval);
	void getPoints(std::vector<cv::Point>& outputPoints, double horInterval, double verInterval);

};

